home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
graphics
/
raymovi2.arc
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-21
|
12KB
|
447 lines
/* main.c
*
*****************************************************************
* *
* basic ray tracing: *
* spheres and a floor (reflection, refraction and diffuse) *
* programmer: friedrich knauss *
* 7-4-86 to 7-21-86 *
* ported to st: allen king 5/87, added: *
* limited color *
* low rez display first *
* .25 to 16 rays per pixel *
* object definitions in file *
* multiple-frame movies *
* bouncing and gravity *
* *
*****************************************************************/
#include <stdio.h>
#include <math.h>
#include <osbind.h>
#include <gemdefs.h>
#include "rtd.h"
#define dprintf if (debug) printf
/* these definitions describe a window in the x-y plane
that the whole thing is viewd through. */
int XMIN, YMIN, XMAX, YMAX;
float xmin, ymax; /* floating pt versions */
wOnewSize(x,y, w,h)
int x,y, w,h;
{ XMIN = x; YMIN = y;
XMAX = x+w+2; YMAX = y+h+2;
}
/* Nomenclature notes:
* 1. <a>P<b> stands for "the number of <a>'s PER <b>
* 2. r stands for rays
* 3. p stands for pixels
* 4. s stands for either side of the screen
* 5. the suffix "Max" denotes the max number compiled into the program
*
* Note: these are linear (not area) conversions. A value of 2 rPp (rays PER
* pixel) is applied in both x and y directions to get an area (and more
* true to life) conversion of 4 (square) rays through each (square) pixel.
*/
float rPp; /* rays PER pixel (on a (linear) side)*/
# define rPpMax 4
/* maximum rays PER pixel (ditto) */
int pPs; /* pixels PER side (of screen) */
int rPs; /* rays PER side (of screen) */
int rPsMax; /* Max rays PER side (of screen) */
#define INC 1
#define INCY (1.25/rPpMax)
#define INCX (1.0/rPpMax)
int colorInd; /* color index (1->b/w, 2->2tones, 3->3tones)*/
#define colors(r,g,b) 1000*(2*(r)+1)/16, 1000*(2*(g)+1)/16, 1000*(2*(b)+1)/16,
int oldClut[16][3], trClut[][3] =
{
#include "colors.h"
0};
struct
{ int (*pal)[][3];
int Navg;
} cConfig[] = {{trClut, 16}, {trClut+16, 32}, {trClut+32, 43}};
FILE *fp, *fopen();
char getline();
char outname[6] = "pearl";
int wHandle;
int pxy_array[4];
#define Nball 15
struct ball bl[Nball];
int level,
nob;
struct vector vp;
float gravity = 0.0, attraction = 0.0;
int step, Step = 1000, bounce = 1;;
int fr=0, frames=1;
int debug =0;
struct sphere ls;
main ()
{ static float xco,
yco, yup;
struct ray rr;
int h, i, j, k;
int c, cr, cg, cb;
int x0, y0, x1, y1, dx, dy, dmax, xMax, yMax;
double red, green, blue; /* was int */
long ctr, BavgN;
float tmp;
char str[200], *buf;
int Navg, *avg, *Bavg;
rPp = 1.0;/* defaults: */
colorInd = 1;
/* graf_mouse(M_OFF, 0L);/**/
printf("\033E");
do
{ printf(" RAYMOVI.PRG\n\n");
printf("Enter scene descriptor\nfilename: ");
if (getline(str, sizeof(str)) == '\003')
exit(0);
printf("\nreading file %s\n", str);
} while(scene_inz(str) == 0);
printf("\033E");
wHandle = w_open(0, "raymovi", 0); /* open window (typeless, menueless) */
w_lClut(cConfig[colorInd-1].pal, oldClut);
v_hide_c(wHandle);
xmin = XMIN; ymax = YMAX;
dx = XMAX-XMIN;
dy = YMAX-YMIN;
if (rPp > 1.0001)
{ BavgN = (long)dx * dy * colorInd;
Bavg = Malloc(BavgN * sizeof(int));
if (Bavg == 0)
{ long l1;
printf("limited to 1 ray/pixel due to insufficient RAM\n");
if (rPp > 1.0)
rPp = 1.0;
for (l1=0; l1<200000; l1++);
}
for (tmp = 1.0; rPp >= 1.0001; tmp *= 2.0, rPp /= 2.0);
}
else
for (tmp = 1.0; rPp < .5001; tmp /= 2.0, rPp *= 2.0);
rPp = tmp;
dmax = (dx>dy)? dx: dy;
for (i=dmax-1, pPs=1; i>0 ; i>>=1, pPs<<=1);
for (i=rPp*pPs-0.5, rPs=1; i>0 ; i>>=1, rPs<<=1);
rPsMax = rPpMax * pPs;
xMax = ((long)rPsMax*dx)/pPs; yMax = ((long)rPsMax*dy)/pPs;
for (; fr<=frames; fr++)
{ int len, len1, p34, x, y, Elen, Ey;
redraw:
if (Bavg) for (avg = Bavg, ctr=0; ctr<BavgN; ctr++)
*avg++ = 0;
Navg = cConfig[colorInd-1].Navg;
ctr = 0;
for (len = rPsMax; len>= rPsMax/rPs; len /=2)
{ p34 = 3;
if (len>=rPpMax)
{ len1 = len/rPpMax - 1;
Elen = 0;
}else
{ len1 = 0;
Elen = rPpMax -1;
Navg *= 4;
}
for (y=0; y<yMax; y += len)
{ p34 = (p34 | 1) ^ 2;
if (Elen)
Ey = (((y + len)&Elen) == 0);
y0 = y/rPpMax;
y1 = y0 + YMIN;
pxy_array[1] = y1;
pxy_array[3] = y1 + len1;
yco = ymax - INCY*y;
for (x=0; x<xMax; x += len)
{ if ((p34 ^=1) == 0 && ctr !=0)
continue;
ctr++;
x0 = x/rPpMax;
x1 = x0 + XMIN;
pxy_array[0] = x1;
pxy_array[2] = x1 + len1;
xco = xmin + INCX*x;
/* define the ray through a pixel; find out value for that pixel */
mv (xco, yco, 0.0, &(rr.org));
sv (&(rr.dir), &(rr.org), &vp);
shade (&rr, &red, &green, &blue); /* find out color */
cb = blue;
cr = red;
cg = green;
if (Bavg) /* compute sum for all rays */
{ register int *array;
array = Bavg + ((long)y0*dx+x0+1)*colorInd;
switch(colorInd)
{ case 3:
cg = *--array += cg;
case 2:
cr = *--array += cr;
case 1:
cb = *--array += cb;
} }
if (Elen==0 || Ey && ((x+len)&Elen) == 0 )
{ switch(colorInd)
{ case 1: /* white (and black): */
c = (cb/Navg + 1) & 0xf; /* white */
break;
case 2: /* white and red: */
if (2*cr < 3*cb)
c = cb/Navg+1 & 7; /* white */
else c = (cr/Navg & 7) + 8; /* red */
break;
case 3: /* white, red, blue: */
if (4*cr > 3*(cg+cb))
{ c = cr/Navg % 6; /* red */
if (c) c += 5; /* red */
else c = 1;
}
else if (4*cb > 3*(cr+cg))
{ c = cb/Navg % 6; /* blue */
if (c) c += 10; /* red */
else c = 1;
}
else c = (cg/Navg+1) % 6; /* white */
break;
}
dprintf("%d,%d,%d -> %d\n", cr, cg, cb, c);
vsf_color(wHandle, c); /*draw colored box*/
v_bar(wHandle, pxy_array);
}
if ((ctr&15)== 0 && kbd() == -1)
goto redraw;
}
sprintf(str, "%s%03d: RAYMOVI.PRG rpp=%05.3f",
outname, fr, (float)ctr/((long)dx*dy));
di_header(1, str);
} }
sprintf(str, "%s%03d.pi1", outname, fr);
f_write(str, colorInd-1);
movie(&bl, nob, step, Step, gravity, bounce, attraction);
write_ckpt("checkpt");
}
exit:
w_lClut(oldClut, (long)0);
w_close();
}
kbd()
{ char key, fname[20];
int found_first = 0, fr1, rval=0;
if (Cconis() == 0)
return(0);
key = Cconin();
while (1)
{ sprintf(fname, "%s%03d.pi1", outname, fr);
switch(key)
{ case ('?'): case ('\0'): /* help */
printf("\033E\n\n RayMovi\n\
\nw - write \"%s\" from screen,\
\nr - read \"%s\" to screen,\
\np - play movie \"%sXXX.pi1\
\ne - exit\n\n", fname, fname, outname);
key = Cconin();
printf("\033E");
rval = -1;
break;
case ('D'):
debug = 1-debug;
return (rval);
case ('w'):
f_write(fname, colorInd-1);
return (rval);
case ('r'): case ('p'):
fr1 = 1;
while (key == 'p' || key == 'r')
{ sprintf(fname,"%s%03d.pi1", outname, fr1++);
if (f_read(fname, (long)0) <0)
{ if (found_first)
{ fr1 = 1;
found_first = 0;
} }
else
found_first = 1;
if (Cconis() != 0 || key == 'r' && found_first)
key = Cconin();
}
rval = -1;
break;
case ('e'): case('\003'):
w_lClut(oldClut, (long)0);
w_close();
exit(0);
default:
return(rval);
} } }
scene_inz(inz_file)
char *inz_file;
{ int h, i, j, k; char str[200], *buf;
if ((fp=fopen(inz_file, "r"))==0)
{ printf("can't open file '%s'\n", inz_file);
return(0);
}
j=0, h=0;
while (1)
{ int linenum;
buf = str;
for (k=0; (i = getc(fp)) != '\n' && i != EOF && ++k<sizeof(str)-1;)
*buf++ = i;
*buf = '\0';
linenum++;
print